package com.lazy.utils.exception;

import com.lazy.utils.utils.ResultUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.constraints.Null;

/**
 * 全局异常处理
 *
 * @author zk
 * @since 2018-05-22 16:39
 */
@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

	/**
	 * 参数校验异常
	 */
	@ExceptionHandler(value = BindException.class)
	@ResponseBody
	public Object bindExceptionErrorHandler(HttpServletRequest req, BindException e) {
		log.error("---BindExceptionErrorHandler Handler---Host {} invokes url {} ERROR: {}", req.getRemoteHost(), req.getRequestURL(), e.getMessage());
		return ResultUtils.errorResult("check params ," + e.getBindingResult().getFieldError().getDefaultMessage());
	}

	/**
	 * 业务异常
	 */
	@ExceptionHandler(value = BusinessException.class)
	@ResponseBody
	public Object businessErrorHandler(HttpServletRequest req, BusinessException e) {
		log.error("---BusinessException Handler---Host {} invokes url {} ERROR: {}", req.getRemoteHost(), req.getRequestURL(), e.getMessage());
		return ResultUtils.errorResult(e);
	}

	/**
	 * 参数异常
	 */
	@ExceptionHandler(value = ParamCheckException.class)
	@ResponseBody
	public Object paramCheckErrorHandler(HttpServletRequest req, ParamCheckException e) {
		log.error("---ParamCheckException Handler---Host {} invokes url {} ERROR: {}", req.getRemoteHost(), req.getRequestURL(), e.getMessage());
		return ResultUtils.errorResult(e);
	}

	/**
	 * 幂等异常
	 */
	@ExceptionHandler(value = IdempotentCheckException.class)
	@ResponseBody
	public Object idempotentCheckErrorHandler(HttpServletRequest req, IdempotentCheckException e) {
		log.error("---IdempotentCheckException Handler---Host {} invokes url {} ERROR: {}", req.getRemoteHost(), req.getRequestURL(), e.getMessage());
		return ResultUtils.errorResult(e);
	}

	/**
	 * 注解校验 异常处理
	 *
	 */
	@ExceptionHandler(value = {ConstraintViolationException.class})
	@ResponseStatus(HttpStatus.BAD_REQUEST)
	@ResponseBody
	public Object constraintViolationExceptionHandler(HttpServletRequest req, ConstraintViolationException e) {
		log.error("---BindExceptionErrorHandler Handler---Host {} invokes url {} ERROR: {}", req.getRemoteHost(), req.getRequestURL(), e.getMessage());
		for (ConstraintViolation<?> s : e.getConstraintViolations()) {
			return ResultUtils.errorResult(s.getMessage());
		}
		return ResultUtils.errorResult("请求参数不合法");
	}

	/**
	 * valid exception
	 *
	 */
	@ExceptionHandler(value = {MethodArgumentNotValidException.class})
	@ResponseStatus(HttpStatus.BAD_REQUEST)
	@ResponseBody
	public Object methodArgumentNotValidExceptionHandler(HttpServletRequest req, MethodArgumentNotValidException e) {
		log.error("---MethodArgumentNotValidException Handler---Host {} invokes url {} ERROR: {}", req.getRemoteHost(), req.getRequestURL(), e.getMessage());
		BindingResult bindingResult = e.getBindingResult();
		StringBuilder errorMesssage = new StringBuilder("Invalid Request:");

		for (FieldError fieldError : bindingResult.getFieldErrors()) {
			errorMesssage.append(fieldError.getDefaultMessage()).append(", ");
		}
		return ResultUtils.errorResult(errorMesssage.toString());
	}

	/**
	 * json 校验
	 *
	 */
	@ExceptionHandler(value = {HttpMessageNotReadableException.class})
	@ResponseStatus(HttpStatus.BAD_REQUEST)
	@ResponseBody
	public Object httpMessageNotReadableExceptionHandler(HttpServletRequest req, HttpMessageNotReadableException e) {
		log.error("---HttpMessageNotReadableException Handler---Host {} invokes url {} ERROR: {}", req.getRemoteHost(), req.getRequestURL(), e.getMessage());
		String errorMesssage = "json参数异常 ";
		return ResultUtils.errorResult(errorMesssage);
	}
}
